﻿using Hotel.Domain;
using SqlSugar;
using System.Linq.Expressions;

namespace Hotel.Repositories
{
    public interface IRepository<TEntity>
        where TEntity : class, new()
    {
        /// <summary>
        /// 是否存在记录
        /// </summary>
        /// <param name="expression"></param>
        /// <returns></returns>
        Task<bool> AnyAsync(Expression<Func<TEntity, bool>> expression);
        /// <summary>
        /// 根据条件删除
        /// </summary>
        /// <param name="expression"></param>
        /// <returns></returns>
        Task<int> DeleteAsync(Expression<Func<TEntity, bool>> expression);
        /// <summary>
        /// 单条根据实体删除
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        Task<int> DeleteAsync(TEntity entity);
        /// <summary>
        /// 批量根据实体删除
        /// </summary>
        /// <param name="entities"></param>
        /// <returns></returns>
        Task<int> DeleteAsync(List<TEntity> entities);
        /// <summary>
        /// 单条删除
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        Task<int> DeleteAsync(long key);
        /// <summary>
        /// 根据条件查单条
        /// </summary>
        /// <param name="expression"></param>
        /// <returns></returns>
        Task<TEntity> FindAsync(Expression<Func<TEntity, bool>> expression);
        /// <summary>
        /// 根据主键查单条
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        Task<TEntity> FindAsync(long key);
        /// <summary>
        /// 根据条件查第一条
        /// </summary>
        /// <param name="expression"></param>
        /// <returns></returns>
        Task<TEntity> FirstAsync(Expression<Func<TEntity, bool>> expression);
        /// <summary>
        /// 同步添加
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        long Insert(TEntity entity);
        /// <summary>
        /// 添加
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        Task<long> InsertAsync(TEntity entity);
        /// <summary>
        /// 根据主键批量删除
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        Task<int> ManyDeleteAsync(List<long> keys);
        /// <summary>
        /// 批量添加
        /// </summary>
        /// <param name="entities"></param>
        /// <returns></returns>
        Task<List<long>> ManyInsertAsync(List<TEntity> entities);
        /// <summary>
        /// 批量更新
        /// </summary>
        /// <param name="entities"></param>
        /// <returns></returns>
        Task<int> ManyUpdateAsyc(List<TEntity> entities);
        /// <summary>
        /// 查全部AS Queryable
        /// </summary>
        /// <returns></returns>
        ISugarQueryable<TEntity> QueryAsQueryable();
        /// <summary>
        /// 查询全部
        /// </summary>
        /// <returns></returns>
        Task<List<TEntity>> QueryAsync();
        /// <summary>
        /// 根据条件查询
        /// </summary>
        /// <param name="expression"></param>
        /// <returns></returns>
        Task<List<TEntity>> QueryAsync(Expression<Func<TEntity, bool>> expression);
        /// <summary>
        /// 根据条件查多条并按某字段排序
        /// </summary>
        /// <param name="expression"></param>
        /// <param name="field">排序字段</param>
        /// <returns></returns>
        Task<List<TEntity>> QueryAsync(Expression<Func<TEntity, bool>> expression, Expression<Func<TEntity, object>> field);
        /// <summary>
        /// 查全部并按某个字段排序
        /// </summary>
        /// <param name="field">排序字段</param>
        /// <returns></returns>
        Task<List<TEntity>> QueryAsync(Expression<Func<TEntity, object>> field);
        /// <summary>
        /// 同步分页
        /// </summary>
        /// <param name="PageSize"></param>
        /// <param name="PageIndex"></param>
        /// <returns></returns>
        (List<TEntity>, int) ToPageList(int PageSize = 10, int PageIndex = 1);
        /// <summary>
        /// 带条件同步分页
        /// </summary>
        /// <param name="expression"></param>
        /// <param name="PageSize"></param>
        /// <param name="PageIndex"></param>
        /// <returns></returns>
        (List<TEntity>, int) ToPageList(Expression<Func<TEntity, bool>> expression, int PageSize = 10, int PageIndex = 1);
        /// <summary>
        /// 按字段排序的分页
        /// </summary>
        /// <param name="sort"></param>
        /// <param name="expression"></param>
        /// <param name="PageSize"></param>
        /// <param name="PageIndex"></param>
        /// <returns></returns>
        Task<(List<TEntity>, int)> ToPageListAsync(Expression<Func<TEntity, object>> sort, Expression<Func<TEntity, bool>> expression, int PageSize = 10, int PageIndex = 1);
        /// <summary>
        /// 异步分页
        /// </summary>
        /// <param name="PageSize"></param>
        /// <param name="PageIndex"></param>
        /// <returns></returns>
        Task<(List<TEntity>, int)> ToPageListAsync(int PageSize = 10, int PageIndex = 1);
        /// <summary>
        /// 带条件异步分页
        /// </summary>
        /// <param name="expression"></param>
        /// <param name="PageSize"></param>
        /// <param name="PageIndex"></param>
        /// <returns></returns>
        Task<(List<TEntity>, int)> ToPageListAsync(Expression<Func<TEntity, bool>> expression, int PageSize = 10, int PageIndex = 1);
        /// <summary>
        /// 更新单条
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        Task<int> UpdateAsyc(TEntity entity);
        /// <summary>
        /// 根据条件更新单条
        /// </summary>
        /// <param name="entity"></param>
        /// <param name="expression"></param>
        /// <returns></returns>
        Task<int> UpdateAsyc(TEntity entity, Expression<Func<TEntity, bool>> expression);
        /// <summary>
        /// 根据条件更新某些字段
        /// </summary>
        /// <param name="entity"></param>
        /// <param name="expression">查询条件</param>
        /// <param name="columns">要更新的字段</param>
        /// <returns></returns>
        Task<int> UpdateAsyc(TEntity entity, Expression<Func<TEntity, bool>> expression, params string[] columns);
        /// <summary>
        /// 更新某些字段
        /// </summary>
        /// <param name="entity"></param>
        /// <param name="columns">要更新的字段</param>
        /// <returns></returns>
        Task<int> UpdateByFieldsAsyc(TEntity entity, params string[] columns);
        /// <summary>
        /// 单条更新并忽略某些字段
        /// </summary>
        /// <param name="entity"></param>
        /// <param name="columns"></param>
        /// <returns></returns>
        Task<int> UpdateAsyc(TEntity entity, params string[] columns);
        /// <summary>
        /// 获取Db上下文
        /// </summary>
        /// <returns></returns>
        ISqlSugarClient GetDbContext();
    }

    public interface IRepository<TEntity, TKey>: IRepository<TEntity>
        where TEntity : class, new()
        where TKey : struct
    {        
        /// <summary>
        /// 单条删除
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        Task<int> DeleteAsync(TKey key);        
        /// <summary>
        /// 根据主键查单条
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        Task<TEntity> FindAsync(TKey key);
        /// <summary>
        /// 根据主键批量删除
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        Task<int> ManyDeleteAsync(List<TKey> keys);        
    }
}